package com.jeeplus.modules.statistics.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.ImmutableMap;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.common.utils.collection.CollectionUtil;
import com.jeeplus.common.web.PageResult;
import com.jeeplus.common.web.Result;
import com.jeeplus.database.datasource.annotation.DS;
import com.jeeplus.modules.statistics.mapper.*;
import com.jeeplus.modules.statistics.model.constant.Constant;
import com.jeeplus.modules.statistics.common.SerialUtils;
import com.jeeplus.modules.statistics.model.domain.*;
import com.jeeplus.modules.statistics.model.query.MassesListQuery;
import com.jeeplus.modules.statistics.model.query.ReserveQuery;
import com.jeeplus.modules.statistics.model.query.StatisticsQuery;
import com.jeeplus.modules.statistics.model.vo.ReserveVO;
import com.jeeplus.modules.statistics.model.vo.ResidentCharts;
import com.jeeplus.modules.statistics.model.vo.StatisticsXY;
import com.jeeplus.modules.sys.utils.UserUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * ClassName: RegionalLocalStatisticsService
 * Function:  各区域下办件群众统估计
 * Date:      2021/3/8 15:05
 *
 * @author hanKongbin
 * version    V1.0
 */
@DS("queuing")
@Service
@RequiredArgsConstructor
@Slf4j
public class RegionalMassesStatisticsService {
    private final CounterService counterService;

    private final SexMapper sexMapper;

    private final AgeMapper ageMapper;

    private final LocalMapper localMapper;

    private final MassesMapper massesMapper;



    /**
     * 性别统计
     *
     * @param query
     * @return
     */
    public Result sexStatistics(StatisticsQuery query) {
        query.setUserid("%"+UserUtils.getUser().getId()+"%");
        List<Map<String, Long>> data = new ArrayList<>();
        try {
            List<SexCount> sexCounts = sexMapper.statistics(query);
            for (SexCount sexCount : sexCounts) {
                Map<String, Long> map = new HashMap<>();
                map.put(sexCount.getSex(), sexCount.getNumber());
                data.add(map);
            }
            //汇总
            long count = sexCounts.stream().mapToLong(SexCount::getNumber).sum();
            return Result.succeed(data, "获取成功！", ImmutableMap.of(Constant.AJAX_JSON_COUNT, count));

        } catch (Exception e) {
            e.printStackTrace();
            log.error("性别统计失败->{}", e.getMessage());
        }
        return Result.failed(data, "获取失败，请联系管理员！");
    }

    /**
     * 年龄统计
     *
     * @param query
     * @return
     */
    public Result ageStatistics(StatisticsQuery query) {
        query.setUserid("%"+UserUtils.getUser().getId()+"%");
        List<Map<String, Long>> data = new ArrayList<>();
        try {
            List<AgeCount> ageCounts = ageMapper.statistics(query);
            for (AgeCount ageCount : ageCounts) {
                Map<String, Long> map = new HashMap<>();
                map.put(ageCount.getAge(), ageCount.getNumber());
                data.add(map);
            }
            //汇总
            long count = ageCounts.stream().mapToLong(AgeCount::getNumber).sum();
            return Result.succeed(data, "获取成功！", ImmutableMap.of(Constant.AJAX_JSON_COUNT, count));
        } catch (Exception e) {
            e.printStackTrace();
            log.error("年龄统计失败->{}", e.getMessage());
        }
        return Result.failed(data, "获取失败，请联系管理员！");
    }

    /**
     * 居民统计
     *
     * @param query
     * @return
     */
    public Result<ResidentCharts> residentStatistics(StatisticsQuery query) {
        ResidentCharts residentCharts = new ResidentCharts();
        // 本市top10
        try {
            query.setUserid("%"+UserUtils.getUser().getId()+"%");
            List<StatisticsXY> localXy = new ArrayList<>();
            List<LocalCount> localCounts = localMapper.localStatistics(query);
            buildLocalCount(query, localXy, localCounts);
            residentCharts.setLocal(localXy);
            residentCharts.setLocalCount(localCounts.stream().mapToLong(LocalCount::getNumber).sum());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("本市户籍统计失败->{}", e.getMessage());
        }
        //非本市top10
        try {
            List<StatisticsXY> nonLocalXy = new ArrayList<>();
            List<LocalCount> nonLocalCounts = localMapper.nonLocalStatistics(query);
            buildLocalCount(query, nonLocalXy, nonLocalCounts);
            residentCharts.setNonLocal(nonLocalXy);
            residentCharts.setNonLocalCount(nonLocalCounts.stream().mapToLong(LocalCount::getNumber).sum());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("非本市户籍统计失败->{}", e.getMessage());
        }
        return Result.succeed(residentCharts, "获取成功！");

    }

    /**
     * 地区统计
     *
     * @param query
     * @return
     */
    public Result cityStatistics(StatisticsQuery query) {
        List<Map<String, Object>> data = new ArrayList<>();
        try {
            query.setUserid("%"+UserUtils.getUser().getId()+"%");
            List<CityCount> cityCounts = localMapper.cityStatistics(query);
            buildCityCount(cityCounts, data);
            //汇总
            long count = cityCounts.stream().mapToLong(CityCount::getNumber).sum();
            return Result.succeed(data, "获取成功！", ImmutableMap.of(Constant.AJAX_JSON_COUNT, count));
        } catch (Exception e) {
            e.printStackTrace();
            log.error("地区统计失败->{}", e.getMessage());
        }
        return Result.failed(data, "获取失败，请联系管理员！");
    }

    /**
     * 全国统计
     *
     * @param query
     * @return
     */
    public Result provinceStatistics(StatisticsQuery query) {
        List<Map<String, Object>> data = new ArrayList<>();
        try {
            query.setUserid("%"+UserUtils.getUser().getId()+"%");
            List<CityCount> cityCounts = localMapper.provinceStatistics(query);
            buildCityCount(cityCounts, data);
            //汇总
            long count = cityCounts.stream().mapToLong(CityCount::getNumber).sum();
            return Result.succeed(data, "获取成功！", ImmutableMap.of(Constant.AJAX_JSON_COUNT, count));
        } catch (Exception e) {
            e.printStackTrace();
            log.error("地区统计失败->{}", e.getMessage());
        }
        return Result.failed(data, "获取失败，请联系管理员！");
    }


    /**
     * 群众办件统计
     *
     * @param query
     * @return
     */
    public PageResult<MassesDealWithCount> dealWithList(MassesListQuery query) {
        PageHelper.startPage(query.getPageNo(), query.getPageSize());
        query.setUserid("%"+UserUtils.getUser().getId()+"%");
        return new PageResult<>(new PageInfo<>(massesMapper.dealWithList(query)), HttpStatus.OK.value());
    }

    /**
     * 群众取号统计
     *
     * @param query
     * @return
     */
    public PageResult<MassesTakeNumberCount> takeNumberList(MassesListQuery query) {
        PageHelper.startPage(query.getPageNo(), query.getPageSize());
        query.setUserid("%"+UserUtils.getUser().getId()+"%");
        return new PageResult<>(new PageInfo<>(massesMapper.takeNumberList(query)), HttpStatus.OK.value());
    }


    /**
     * 全国统计实例构造
     *
     * @param cityCounts
     * @param data
     */
    private void buildCityCount(List<CityCount> cityCounts, List<Map<String, Object>> data) {
        for (CityCount cityCount : cityCounts) {
            Map<String, Object> map = new HashMap<>();
            if(StringUtils.isBlank(cityCount.getName()))cityCount.setName("其他");
            map.put(cityCount.getName(), cityCount.getNumber());
            data.add(map);
        }
    }

    /**
     * 居民统计实例构造
     *
     * @param query
     * @param localXy
     * @param localCounts
     */
    private void buildLocalCount(StatisticsQuery query, List<StatisticsXY> localXy, List<LocalCount> localCounts) {
        for (LocalCount localCount : localCounts) {
            StringBuilder xLabel = new StringBuilder();
            xLabel.append(localCount.getBusName());
            Optional.ofNullable(localCount.getBusChar()).ifPresent(e -> xLabel.append("(").append(e).append(")"));
            List<String> counters = counterService.findCounterNoBySerialNo(SerialUtils.buildSerial(localCount.getSerialNo(), 3), query.getAreaId());
            if (!CollectionUtil.isEmpty(counters)) {
                String counterName = counters.stream().map(e -> e + "号").collect(Collectors.joining(" "));
                xLabel.append("[").append(counterName).append("]");
            }
            localXy.add(new StatisticsXY(xLabel.toString(), localCount.getNumber()));
        }
    }
}
